#include "head.h"
// 单链表的创建
u_list *init_link_list(void)
{
    // 1 创建 头节点的动态空间
    u_list *list = (u_list *)malloc(sizeof(u_list));
    if (NULL == list)
    {
        ERRLOG("创建失败");
        return NULL;
    }

    list->next = NULL;

    return list;
}

// 单向链表的遍历
void print_link_list(u_list *list)
{
    // 安全判断
    if (NULL == list)
    {
        ERRLOG("链表 为 NULL");
        return;
    }
    if (NULL == list->next)
    {
        ERRLOG("表数据为空");
        return;
    }

    u_node *ptr = list->next;
    printf("用户名\t密码\t身份证信息\t余额\t折扣\t身份\n");
    for (size_t i = 0; NULL != ptr; i++)
    {
        printf("%s\t", ptr->userm.name);
        printf("%s\t", ptr->userm.passwd);
        printf("%s\t", ptr->userm.IDcard);
        printf("%d\t", ptr->userm.value);
        printf("%.1f\t", ptr->userm.rate);
        printf("%d\t", ptr->userm.grade);
        if (ptr->userm.ticket[0].id != -1)
        {
            printf("%-8d", ptr->userm.ticket->id);                                                       // 航班班次
            printf("%-16s", ptr->userm.ticket->flighttype);                                              // 飞机机型
            printf("%-12s", ptr->userm.ticket->startcity);                                               // 航班起点站
            printf("%-12s", ptr->userm.ticket->arrivecity);                                              // 航班终点站
            printf("%02d:%02d\t", ptr->userm.ticket->starttime[0], ptr->userm.ticket->starttime[1]);     // 起飞时间
            printf("%02d:%02d\t\t", ptr->userm.ticket->arrivetime[0], ptr->userm.ticket->arrivetime[1]); // 到达时间
            printf("%-10s\t", ptr->userm.ticket->flytime);                                               // 飞行时间
            printf("%-8d", ptr->userm.ticket->value);                                                    // 票价
            printf("%-8d", ptr->userm.ticket->maxNUM);                                                   // 额定载客量
            printf("%-10d", ptr->userm.ticket->leftbuyersa);                                             // 剩余座位数量
            printf("%c\t", ptr->userm.ticket->whetherfly);
        }

        puts("");
        ptr = ptr->next;
    }
    return;
}

// 单向链表的插入
void insert_node(u_list *list, user_t data, int pos)
{
    // 安全判断
    if (NULL == list)
    {
        ERRLOG("表为NULL");
        return;
    }

    u_node *new_node = (u_node *)malloc(sizeof(u_node)); // 创建结点
    if (NULL == new_node)
    {
        ERRLOG("new_node 创建动态内存失败");
        return;
    }

    new_node->userm = data;
    //==========================头插==========================
    if (1 == pos)
    {
        // 新节点的next 指向头节点的next
        new_node->next = list->next;
        // 头节点next 指向新节点
        list->next = new_node;
        return;
    }

    //==========================任意位置插入==========================
    u_node *ptr = list->next;

    for (size_t i = 1; i < pos - 1 && NULL != ptr; i++)
    {
        ptr = ptr->next;
    }
    if (NULL == ptr)
    {
        ERRLOG("ptr 已经指向 NULL");
        free(new_node);
        return;
    }

    // 开始插入
    // 新节点的next 指向 ptr 的next
    new_node->next = ptr->next;
    // ptr 的next 指向 新节点
    ptr->next = new_node;

    return;
}

// 单向链表按用户名删除
void delete_node_name(u_list *list, char *name)
{
    if (NULL == list)
    {
        ERRLOG("链表的动态空间为空");
        return;
    }
    if (NULL == list->next)
    {
        ERRLOG("链表内无数据");
        return;
    }

    u_node *ptr = list->next;
    size_t i = 0;
    for (i = 0; NULL != ptr; i++)
    {
        if (!strcmp(ptr->userm.name, name))
        {
            delete_node(list, i + 1);
            return;
        }
        ptr = ptr->next;
    }

    return;
}

// 单向链表的删除 idex从1 开始
void delete_node(u_list *list, int pos)
{
    // 安全判断
    if (NULL == list)
    {
        ERRLOG("表为NULL");
        return;
    }
    if (NULL == list->next)
    {
        ERRLOG("表内无数据");
        return;
    }

    u_node *ptr_1 = list->next;
    u_node *ptr_2 = NULL;
    for (size_t i = 1; i < pos - 1 && NULL != ptr_1; i++)
    {
        ptr_1 = ptr_1->next;
    }

    if (NULL == ptr_1)
    {
        ERRLOG("ptr 已经指向 NULL");
        return;
    }

    if (1 == pos)
    {
        list->next = ptr_1->next;
        free(ptr_1);
    }
    else
    {
        // 指向要删除的节点 ptr_2
        ptr_2 = ptr_1->next;

        // 1.ptr_1 的 next 指向 ptr_2 的 next
        ptr_1->next = ptr_2->next;
        // 2.释放ptr_2
        free(ptr_2);
    }
}

// 单向链表的查找
u_node *find_node_id(u_list *list, int pos)
{
    // 安全判断
    if (NULL == list)
    {
        ERRLOG("表为NULL");
        return NULL;
    }
    if (NULL == list->next)
    {
        ERRLOG("表内无数据");
        return NULL;
    }

    u_node *ptr = list->next;
    for (size_t i = 1; i < pos; i++)
    {
        ptr = ptr->next;
    }
    return ptr;
}

u_node *find_node_name(u_list *list, char *name)
{
    // 安全判断
    if (NULL == list)
    {
        ERRLOG("表为NULL");
        return NULL;
    }
    if (NULL == list->next)
    {
        ERRLOG("表内无数据");
        return NULL;
    }
    u_node *ptr = list->next;

    for (size_t i = 0; NULL != ptr; i++)
    {
        if (!strcmp(ptr->userm.name, name))
        {
            return ptr;
        }
        ptr = ptr->next;
    }

    return NULL;
}

// 单向链表的清空
void clear_link_list(u_list *list)
{
    // 安全判断
    if (NULL == list)
    {
        ERRLOG("表为NULL");
        return;
    }
    if (NULL == list->next)
    {
        ERRLOG("表内无数据");
        return;
    }

    // 1 销毁节点
    u_node *ptr_1 = list->next;
    u_node *ptr_2 = ptr_1->next;
    for (size_t i = 0; ptr_1 != NULL; i++)
    {
        free(ptr_1);
        ptr_1 = ptr_2;
        if (NULL != ptr_2)
        {
            ptr_2 = ptr_2->next;
        }
    }

    list->next = NULL;
}

// 单链表的合并
u_list *merge_link_lists(u_list *list1, u_list *list2)
{
    // 安全判断
    if (NULL == list1 && NULL == list2)
    {
        ERRLOG("表为NULL\n");
        return NULL;
    }
    if (NULL == list1->next && NULL == list2->next)
    {
        ERRLOG("表内无数据\n");
        return NULL;
    }

    u_list *list3 = init_link_list();

    u_node *ptr_1 = list1->next;
    size_t i = 0;
    for (i = 1; NULL != ptr_1; i++)
    {
        insert_node(list3, ptr_1->userm, i);
        ptr_1 = ptr_1->next;
    }

    ptr_1 = list2->next;
    for (; NULL != ptr_1; i++)
    {
        insert_node(list3, ptr_1->userm, i);
        ptr_1 = ptr_1->next;
    }

    return list3;
}

// 单链表的销毁
void free_link_list(u_list **list)
{
    if (NULL == *list)
    {
        ERRLOG("链表 为 NULL");
        return;
    }

    // 1 销毁结点
    u_node *ptr_1 = (*list)->next;
    u_node *ptr_2 = ptr_1->next;
    for (size_t i = 0; ptr_1 != NULL; i++)
    {
        free(ptr_1);
        // if 判断  判断 ptr2 = NULL 的时候 我们如何处理
        ptr_1 = ptr_2;
        if (NULL != ptr_2)
        {
            ptr_2 = ptr_2->next;
        }
    }

    // 2 销毁头结点
    free(*list);
    *list = NULL;
}

// 用户信息写入文件
void F_u_print(u_list *list, const char *file_name)
{
    FILE *fp = fopen(file_name, "w+");
    if (NULL == fp)
    {
        ERRLOG("文件创建失败");
        return;
    }
    // 光标移动到开头
    fseek(fp, 0, SEEK_SET);

    u_node *ptr = list->next;
    // 遍历写入
    for (size_t i = 0; NULL != ptr; i++)
    {
        fprintf(fp, "%s\t%s\t%s\t%d\t%f\t%d\t", ptr->userm.name, ptr->userm.passwd, ptr->userm.IDcard, ptr->userm.value, ptr->userm.rate, ptr->userm.grade);

        fprintf(fp, "%d\t%s\t%s\t%s\t%d:%d\t%d:%d\t%s\t%d\t%d\t%d\t%c\n",
                ptr->userm.ticket->id, ptr->userm.ticket->flighttype, ptr->userm.ticket->startcity, ptr->userm.ticket->arrivecity, ptr->userm.ticket->starttime[0], ptr->userm.ticket->starttime[1], ptr->userm.ticket->arrivetime[0],
                ptr->userm.ticket->arrivetime[1], ptr->userm.ticket->flytime, ptr->userm.ticket->value, ptr->userm.ticket->maxNUM, ptr->userm.ticket->leftbuyersa, ptr->userm.ticket->whetherfly);
        ptr = ptr->next;
    }

    fclose(fp);
}

// 从用户文件中读取
void F_u_scanf(u_list *list, const char *file_name)
{
    if (NULL == list)
    {
        ERRLOG("单循环链表 为 NULL");
        return;
    }
    FILE *fp = fopen(file_name, "r");
    if (NULL == fp)
    {
        ERRLOG("文件创建失败");
        return;
    }
    // 移动光标到头
    fseek(fp, 0, SEEK_SET);

    // 判断文件行数
    char ch = 0; // 接收文件的字符
    int pos = 0; // 判断文件的行数
    user_t userm;
    while (EOF != (ch = fgetc(fp)))
    {
        if ('\n' == ch)
        {
            pos++;
        }
    }

    fflush(fp); // 刷新文件

    // 移动光标到头
    fseek(fp, 0, SEEK_SET);

    for (size_t i = 0; i < pos; i++)
    {
        fscanf(fp, "%s\t%s\t%s\t%d\t%f\t%d\t",
               userm.name, userm.passwd, userm.IDcard, &userm.value, &userm.rate, &userm.grade);

        fscanf(fp, "%d\t%s\t%s\t%s\t%d:%d\t%d:%d\t%s\t%d\t%d\t%d\t%c\n",
               &userm.ticket->id, userm.ticket->flighttype, userm.ticket->startcity, userm.ticket->arrivecity, &userm.ticket->starttime[0], &userm.ticket->starttime[1], &userm.ticket->arrivetime[0],
               &userm.ticket->arrivetime[1], userm.ticket->flytime, &userm.ticket->value, &userm.ticket->maxNUM, &userm.ticket->leftbuyersa, &userm.ticket->whetherfly);
        

        insert_node(list, userm, i + 1);
    }

    fflush(fp); // 刷新文件
    fclose(fp);
    return;
}


// 自定义memset将用户的航班信息初始化
void my_memset(f_data *ticket)
{
    // 初始化整数类型和字符类型（单个字符，不是字符数组）
    ticket->id = -1; // 表示无效航班ID
    ticket->starttime[0] = 00;
    ticket->starttime[1] = 00;
    ticket->arrivetime[0] = 00;
    ticket->arrivetime[1] = 00;
    ticket->leftbuyersa = 0;
    ticket->value = 0;
    ticket->maxNUM = 0;
    ticket->whetherfly = 'n';
    strcpy(ticket->flighttype, "无");
    strcpy(ticket->startcity, "无");
    strcpy(ticket->arrivecity, "无");
    strcpy(ticket->flytime, "无");


    // 对字符数组不做特殊处理，保持它们的原始值
}